﻿using System.Reflection.Metadata;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Xml.Linq;
using TDMS.Net.Internals;
#pragma warning disable CS8604 // Possible null reference argument.

namespace TDMS.Net;

using static NiLibDDC;

public class TdmsFile : TdmsContainerObject<TdmsChannelGroup>, IDisposable
{
    private bool _disposed;

    public string FilePath { get; }

    public ETdmsFileType FileType { get; }

    public string Title { get; }

    public string Author { get; }

    public bool IsReadOnly { get; private set; }

    private TdmsFile(string filePath,
        ETdmsFileType fileType = ETdmsFileType.TDMS,
        string name = "",
        string description = "",
        string title = "",
        string author = "")
    {
        FilePath = filePath;
        FileType = fileType;
        Name = name;
        Description = description;
        Title = title;
        Author = author;
    }

    public static TdmsFile Create(string filePath,
        ETdmsFileType fileType = ETdmsFileType.TDMS,
        string name = "",
        string description = "",
        string title = "",
        string author = "")
    {
        var tdms = new TdmsFile(filePath, fileType, name, description, title, author);
        tdms.IsReadOnly = false;
        var fileHandle = new IntPtr();
        ExceptionBuilder.CheckApiStatus(DDC_CreateFile(filePath, fileType.ToString(), name, description, title, author, ref fileHandle));
        tdms.Handle = fileHandle;
        return tdms;
    }

    public static TdmsFile OpenRead(string filePath, ETdmsFileType fileType = ETdmsFileType.TDMS)
    {
        var tdms = new TdmsFile(filePath, fileType, string.Empty, string.Empty, string.Empty, string.Empty);
        tdms.IsReadOnly = true;
        var fileHandle = new IntPtr();
        ExceptionBuilder.CheckApiStatus(DDC_OpenFileEx(filePath, fileType.ToString(), 1, ref fileHandle));
        tdms.Handle = fileHandle;
        return tdms;
    }

    public static TdmsFile OpenWrite(string filePath, ETdmsFileType fileType = ETdmsFileType.TDMS)
    {
        var tdms = new TdmsFile(filePath, fileType, string.Empty, string.Empty, string.Empty, string.Empty);
        tdms.IsReadOnly = false;
        var fileHandle = new IntPtr();
        ExceptionBuilder.CheckApiStatus(DDC_OpenFileEx(filePath, fileType.ToString(), 0, ref fileHandle));
        tdms.Handle = fileHandle;
        return tdms;
    }


    public TdmsChannelGroup CreateChannelGroup(string name, string description)
    {
        var groupHandle = new IntPtr();
        ExceptionBuilder.CheckApiStatus(DDC_AddChannelGroup(Handle, name, description, ref groupHandle));
        var group = new TdmsChannelGroup(groupHandle, this, name, description);
        Children.Add(group);
        return group;
    }

    public void Save()
    {
        ExceptionBuilder.CheckApiStatus(DDC_SaveFile(Handle));
    }

    #region  Dispose

    private void ReleaseUnmanagedResources()
    {
        ExceptionBuilder.CheckApiStatus(DDC_CloseFile(Handle));
    }

    protected virtual void Dispose(bool disposing)
    {
        ReleaseUnmanagedResources();
        if (disposing)
        {
        }
    }

    public void Dispose()
    {
        if (_disposed) return;
        _disposed = true;
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    ~TdmsFile()
    {
        Dispose(false);
    }

    #endregion
}